unit PaymentReceivedForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.DBGrids, Vcl.ExtCtrls,
  DBModule, Vcl.StdCtrls, Vcl.DBCtrls, Vcl.ComCtrls, UserUtils, IB, Data.DB;

type
  TfmPaymentReceived = class(TForm)
    DBGrid1: TDBGrid;
    Label1: TLabel;
    Label2: TLabel;
    DBGrid2: TDBGrid;
    GroupBox1: TGroupBox;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    dtReceivedDate: TDateTimePicker;
    txtAmountReceived: TEdit;
    dbcbPaymentType: TDBLookupComboBox;
    chkReceived: TCheckBox;
    btnUpdate: TButton;
    btnClose: TButton;
    Label6: TLabel;
    txtPaymentDetails: TEdit;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure txtAmountReceivedKeyPress(Sender: TObject; var Key: Char);
    procedure txtAmountReceivedExit(Sender: TObject);
    procedure DBGrid1KeyPress(Sender: TObject; var Key: Char);
    procedure DBGrid1TitleClick(Column: TColumn);
    procedure btnCloseClick(Sender: TObject);
    procedure btnUpdateClick(Sender: TObject);
    procedure dbcbPaymentTypeDropDown(Sender: TObject);
    procedure DBGrid1CellClick(Column: TColumn);
    procedure FormCreate(Sender: TObject);
    procedure chkReceivedClick(Sender: TObject);
  private
    { Private declarations }
    procedure EmptyFields;
    procedure RefreshDB;
    procedure AutoFill;
  public
    { Public declarations }
  end;

var
  fmPaymentReceived: TfmPaymentReceived;

implementation

{$R *.dfm}

procedure TfmPaymentReceived.btnCloseClick(Sender: TObject);
begin
  Close;
end;

procedure TfmPaymentReceived.btnUpdateClick(Sender: TObject);
var
  Amount: Single;
  CurrentID: Integer;

begin
  if not DBGrid1.DataSource.DataSet.FieldByName('PAID').AsBoolean then
  begin
    if not chkReceived.Checked then
    begin
      ShowMessage('Received is not checked.');
      chkReceived.SetFocus;
      Exit;
    end;
    CurrentID := DBGrid1.DataSource.DataSet.FieldByName('ID').AsInteger;
    Amount := StrToFloat(txtAmountReceived.Text);
    if Amount <= 0 then
    begin
      ShowMessage('No payment has recevied.');
      txtAmountReceived.SetFocus;
      Exit;
    end;
    if dbcbPaymentType.KeyValue = '' then
    begin
      ShowMessage('Please choose a Payment Type.');
      dbcbPaymentType.SetFocus;
      Exit;
    end;

    with DataModule1.qrySQL do
    begin
      SQL.Clear;
      Params.Clear;
      try
        try
          SQL.Add('Update INVOICE Set PAID=:Paid, AMOUNT_RECEIVED=:Amount, ' +
                  'PAYMENT_TYPE=:PaymentType, PAYMENT_RECEIVED_DATE=:PaymentReceivedDate, ' +
                  'PAYMENT_DETAILS=:PaymentDetails, ' +
                  'UPDATE_DATE=CURRENT_TIMESTAMP Where ID=:ID');
          Params.ParamByName('Paid').AsString := BoolToStr(chkReceived.Checked, True);
          Params.ParamByName('Amount').AsFloat := Amount;
          Params.ParamByName('PaymentType').AsString := VarToStr(dbcbPaymentType.KeyValue);
          Params.ParamByName('PaymentDetails').AsString := Trim(txtPaymentDetails.Text);
          Params.ParamByName('PaymentReceivedDate').AsDate := dtReceivedDate.Date;
          Params.ParamByName('ID').AsInteger := DBGrid1.DataSource.DataSet.FieldByName('ID').AsInteger;
          if not Prepared then
            Prepare;
          ExecSQL;
          Transaction.Commit;
          EmptyFields;
        except
          on E: EIBInterBaseError do
          begin
            Transaction.Rollback;
            ShowMessage(Format('IBErrorCode=%d, SQLCode=%d, Msg=%s, StackTrace=%s', [E.IBErrorCode, E.SQLCode, E.Message, E.StackTrace]));
          end;
        end;
      finally
        RefreshDB;
        DBGrid1.DataSource.DataSet.Locate('ID', CurrentID, [loPartialKey]);
      end;
    end;
  end else
    ShowMessage('Invoice is PAID, no amendment allowed.');
end;

procedure TfmPaymentReceived.chkReceivedClick(Sender: TObject);
begin
    dtReceivedDate.Enabled := chkReceived.Checked;
    txtAmountReceived.Enabled := chkReceived.Checked;
    dbcbPaymentType.Enabled := chkReceived.Checked;
    txtPaymentDetails.Enabled := chkReceived.Checked;
    btnUpdate.Enabled := chkReceived.Checked;
end;

procedure TfmPaymentReceived.dbcbPaymentTypeDropDown(Sender: TObject);
begin
  with dbcbPaymentType.ListSource.DataSet do
  begin
    if not Active then
      Open;
    Last;
    First;
  end;
end;

procedure TfmPaymentReceived.DBGrid1CellClick(Column: TColumn);
begin
  AutoFill;
end;

procedure TfmPaymentReceived.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
  case Key of
    Char(VK_TAB):
      chkReceived.SetFocus;
    Char(VK_RETURN):
      AutoFill;
  end;
end;

procedure TfmPaymentReceived.DBGrid1TitleClick(Column: TColumn);
var
  ID: integer;
begin
  ID := DBGrid1.DataSource.DataSet.FieldByName('ID').AsInteger;
  DataModule1.qryInvoiceList.Active := False;
  DataModule1.qryInvoiceList.SQL.Text := SQLBeforeClause(DataModule1.qryInvoiceList.SQL.Text, 'ORDER BY') + ' ORDER BY "' + Column.FieldName + '"';
  DataModule1.qryInvoiceList.Open;
  DBGrid1.DataSource.DataSet.Locate('ID', ID, []);
end;

procedure TfmPaymentReceived.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  FreeAndNil(fmPaymentReceived);
end;

procedure TfmPaymentReceived.FormCreate(Sender: TObject);
begin
  SetLength(TrueBoolStrs, 1);
  SetLength(FalseBoolStrs, 1);
  TrueBoolStrs[0] := 'Y';
  FalseBoolStrs[0] := 'N';
  with DataModule1 do
  begin
    fbPaymentType.Active := True;
    fbPaymentType.Last;
    fbPaymentType.First;
  end;

end;

procedure TfmPaymentReceived.txtAmountReceivedExit(Sender: TObject);
begin
  txtAmountReceived.Text := Format('%.2f', [StrToFloat(txtAmountReceived.Text)]);
end;

procedure TfmPaymentReceived.txtAmountReceivedKeyPress(Sender: TObject;
  var Key: Char);
var
  i: integer;
begin
  case Key of
    '0' .. '9':;
    '.': begin
           i := Pos('.', txtAmountReceived.Text);
           if i > 0 then
           begin
             Key := #0;
             txtAmountReceived.SelStart := i + 1;
             txtAmountReceived.SelLength := Length(txtAmountReceived.Text) - i;
           end;
         end;
    Char(VK_BACK):;
    else
      Key := Char(0);
  end;
end;

procedure TfmPaymentReceived.EmptyFields;
begin
  txtAmountReceived.Text := '0.00';
  dbcbPaymentType.KeyValue := '';
  chkReceived.Checked := False;
end;

procedure TfmPaymentReceived.RefreshDB;
begin
  with DataModule1 do
  begin
    with qryInvoiceList do
    begin
      if not Active then
        Open;
      Last;
      First;
    end;
    with fbInvoiceDetails do
    begin
      if not Active then
        Open;
      Last;
      First;
    end;
    with fbPaymentType do
    begin
      if not Active then
        Open;
      Last;
      First;
    end;
  end;
end;

procedure TfmPaymentReceived.AutoFill;
var
  Paid: Boolean;
begin
  with DBGrid1.DataSource.DataSet do
  begin
    if not TryStrToBool(FieldByName('PAID').AsString, Paid) then
      Paid := False;
    chkReceived.Checked := Paid;
    dtReceivedDate.Date := FieldByName('PAYMENT_RECEIVED_DATE').AsDateTime;
    txtAmountReceived.Text := Format('%.2f', [FieldByName('TOTAL_AMOUNT').AsFloat]);
    dbcbPaymentType.KeyValue := FieldByName('PAYMENT_TYPE').AsVariant;
    txtPaymentDetails.Text := FieldByName('PAYMENT_DETAILS').AsString;
    chkReceived.Enabled := not Paid;
    dtReceivedDate.Enabled := not Paid;
    txtAmountReceived.Enabled := not Paid;
    dbcbPaymentType.Enabled := not Paid;
    btnUpdate.Enabled := not Paid;
    txtPaymentDetails.Enabled := not Paid;
  end;
end;

end.
